/******************************************************************************/
//	Direct3DManager.h	-	A Manager to handle all Direct3D needs.
//
//	Author:		Russell Klinkerman
//	Created:	02.24.2004
/******************************************************************************/

#ifndef _D3DMANAGER_H_
#define _D3DMANAGER_H_

#include <d3dx9tex.h>	// Includes windows.h d3d9.h, and d3dx9core.h
#include <dxerr.h>		// DirectX Error Reporting Functions.

//#include "AlertManager.h"

// Direct3D Libraries
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "dxerr.lib")

/**********/
/* MACROS */
/**********/
#ifdef _ALERTMANAGER_H_

#ifndef POSTERR	// DirectX Errors get passed to the AlertManager, if it is being used.
	#define	POSTERR(x)	(alertManager.PostAlert( DXGetErrorDescription( (x) ) ))	
#endif

#else

#ifndef POSTERR	// DirectX Errors get passed via MessageBox, if AlertManager is not being used.
	#define	POSTERR(x)	MessageBox(NULL, DXGetErrorDescription( (x) ), "Error", MB_OK)
#endif

#endif

#define	PI_OVER_FOUR	0.7853981635

enum	DXM_FONT_SIZE { DXMF_SMALL, DXMF_MED, DXMF_LARGE };
enum	DXM_PROJECTION	{	DXMP_PERSPECTIVE, DXMP_ORTHO };

// The Direct3D Manager Class
class	CDirect3DManager
{
	private:

		//	The D3D Presentation Parameters.
		D3DPRESENT_PARAMETERS	D3DPresentParams;

		// Pointer to the Direct3D Interface.
		IDirect3D9			*	pDirect3DInterface;	

		// Pointer to the Direct3D Device.
		IDirect3DDevice9	*	pDirect3DDevice;

		// The apdaptor's display settings (width, height, refresh)
		D3DDISPLAYMODE displaySettings;

		/************/
		// MATRICES

		D3DXMATRIX projectionMatrix;
		D3DXMATRIX viewMatrix;

		/************/
		// FONTS

		LPD3DXFONT pFont;

		/************/
		// SPRITES

		LPD3DXSPRITE pSpriteInterface;
		D3DXMATRIX * pCurrentSpriteMatrix;

		// Copy Constructor
		CDirect3DManager(const CDirect3DManager &obj);

		// Assignment Operator
		CDirect3DManager &operator=(const CDirect3DManager &obj);

	public:

		// constructor
		CDirect3DManager(){}

		// destructor
		~CDirect3DManager(){}

		/******************************************************************************/
		//	Init	-	Initializes Direct3D
		//
		//	In:
		//	Out:
		//	Return:	TRUE if successful
		/******************************************************************************/
		bool	Init();

		/******************************************************************************/
		//	SetProjection	-	Sets up a projection matrix for Direct3D
		//
		//	In:		eProjection		-	The type of projection to create.
		//			fNearPlane		-	The near clipping plane of the projection
		//			fFarPlane		-	The far clipping plane of the projection
		//			fFieldOfView	-	The field of view for the projection ( Note: Only used
		//									for perspective matrices [SpaceWidth/SpaceHeight] )
		//	Out:
		//	Return:	TRUE if successful
		/******************************************************************************/
		void	SetProjection(DXM_PROJECTION eProjection, float	fNearPlane = 1.0f,
								float fFarPlane = 500.0f, float fFieldOfView = D3DX_PI/3);

		/******************************************************************************/
		//	Clear	-	Clears the Backbuffer
		//
		//	In:		+ dwFlags		-	Surfaces to be cleared (target, depth, stencil, etc.)
		//			+ nRed,
		//			  nGreen,
		//			  nBlue			-	The RGB to paint the cleared surfaces.
		//			+ nRectsToClear	-	The number of rectangles we are clearing.
		//			+ pRectsToClear	-	The rectangles we are clearing.
		//	Out:
		//	Return:	TRUE if successful
		/******************************************************************************/
		void	Clear(int nRed = 0, int nGreen = 0, int nBlue = 0, DWORD dwFlags = D3DCLEAR_TARGET, 
						int nRectsToClear = 0, const D3DRECT * pRectsToClear = NULL);

		/******************************************************************************/
		//	Text	-	Draws text to the backbuffer.
		//
		//	In:		+ strText	-	The text to draw (C-Style NULL terminated string)
		//			+ nX		-	The X Coordinate of the text to draw.
		//			+ nY		-	The Y Coordinate of the text to draw.
		//			+ eSize		-	The size of the text to draw (see DXM_FONT_SIZE enum for valid values)
		//			+ nRed,
		//			  nGreen,
		//			  nBlue		-	The RGB to paint the text.
		//	Out:
		//	Return:
		/******************************************************************************/
		void	Text(char * strText, int nX = 0, int nY = 0, int nRed = 255, int nGreen = 255, int nBlue = 255, bool bShadow = true, DXM_FONT_SIZE eSize = DXMF_SMALL);

		void	BeginSprites();

		/******************************************************************************/
		//	Sprite	-	Draws a sprite to the screen
		//
		//	In:		+ pTexture	-	The D3D Texture to render
		//			+ pmSprite	-	A D3DXMATRIX representing the sprite's position, scale, and rotation
		//			+ dxColor	-	The color/alpha levels (default = WHITE/SOLID, use D3DCOLOR_RGBA )
		//			+ pvCenter	-	A D3DXVECTOR3 representing the center of the sprite
		//			+ prSource	-	A RECT representing the section of pTexture to render.
		//	Out:
		//	Return:
		/******************************************************************************/
		void	Sprite(LPDIRECT3DTEXTURE9 pTexture, D3DXMATRIX * pmSprite, D3DCOLOR dxColor = 0xFFFFFFFF,
							D3DXVECTOR3 * pvCenter = NULL, RECT * prSource = NULL);

		void	EndSprites();

		/******************************************************************************/
		//	Show	-	Present the Backbuffer
		//
		//	In:
		//	Out:
		//	Return:	TRUE if successful
		/******************************************************************************/
		void	Show();

		/******************************************************************************/
		//	Shutdown	-	Releases and Shuts down Direct3D
		//
		//	In:
		//	Out:
		//	Return:	TRUE if successful
		/******************************************************************************/
		bool	Shutdown();

		// The following is only included if the AlertManager is also being used.
		#ifdef _ALERTMANAGER_H_
		
			/******************************************************************************/
			//	ShowAlerts	-	Displays all errors that are in the AlertManager
			//
			//	In:
			//	Out:
			//	Return:
			/******************************************************************************/
			bool	ShowAlerts();

		#endif

		/*************/
		/* ACCESSORS */

		// GetDevice	-	Return pointer to the D3D Device
		IDirect3DDevice9	*	GetDevice() { return pDirect3DDevice; }

		// GetInterface	-	Return pointer to the D3D Interface
		IDirect3D9	*	GetInterface() { return pDirect3DInterface; }

		// GetAdapterResolution - Sends back the screen resolution
		void	GetAdapterResolution(int &nWidth, int &nHeight)
		{
			nWidth = displaySettings.Width;
			nHeight = displaySettings.Height;
		}

};

extern CDirect3DManager d3dManager;

#endif